home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / __tioctl.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  7KB  |  292 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  __tioctl.c,v 1.1.1.1 1994/04/04 04:30:13 amiga Exp
  20.  *
  21.  *  __tioctl.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:13  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.5  1993/11/05  21:51:08  mw
  26.  *  seems I got oldstyle tty handling oposite way..
  27.  *
  28.  *  Revision 1.4  1992/08/09  20:39:01  amiga
  29.  *  add a cast to get rid of a warning
  30.  *
  31.  *  Revision 1.3  1992/07/04  19:07:25  mwild
  32.  *  send DISK_INFO packet with synchronous port, async delivery seems to be
  33.  *  broken with CNC:
  34.  *
  35.  * Revision 1.2  1992/06/08  02:36:00  mwild
  36.  * fix TIOCGWINSZ, row/column was off by one
  37.  *
  38.  * Revision 1.1  1992/05/14  19:55:40  mwild
  39.  * Initial revision
  40.  *
  41.  */
  42.  
  43. #define KERNEL
  44. #include "ixemul.h"
  45. #include "kprintf.h"
  46. #include <sgtty.h>
  47. #define OB0    B0    
  48. #define OB50    B50    
  49. #define OB75    B75    
  50. #define OB110    B110    
  51. #define OB134    B134    
  52. #define OB150    B150    
  53. #define OB200    B200    
  54. #define OB300    B300    
  55. #define OB600    B600    
  56. #define OB1200    B1200    
  57. #define    OB1800    B1800    
  58. #define OB2400    B2400    
  59. #define OB4800    B4800    
  60. #define OB9600    B9600    
  61. #define OEXTA    EXTA    
  62. #define OEXTB    EXTB    
  63. #undef B0    
  64. #undef B50    
  65. #undef B75    
  66. #undef B110    
  67. #undef B134    
  68. #undef B150    
  69. #undef B200    
  70. #undef B300    
  71. #undef B600    
  72. #undef B1200    
  73. #undef B1800    
  74. #undef B2400    
  75. #undef B4800    
  76. #undef B9600    
  77. #undef EXTA    
  78. #undef EXTB    
  79. #include <sys/termios.h>
  80. #include <ctype.h>
  81. #include <devices/conunit.h>
  82.  
  83. #if __GNUC__ != 2
  84. #define alloca __builtin_alloca
  85. #endif
  86.  
  87. /* IOCTLs on "interactive" files */
  88.  
  89. int
  90. __tioctl(struct file *f, unsigned int cmd, unsigned int inout, 
  91.      unsigned int arglen, unsigned int arg)
  92. {
  93.   int omask, result, err;
  94.  
  95.   omask = syscall (SYS_sigsetmask, ~0);
  96.   __get_file (f);
  97.   result = -1;
  98.  
  99.   if (/*!IsInteractive(CTOBPTR(f->f_fh))*/ ! f->f_fh->fh_Port)
  100.     {
  101.       err = ENOTTY;
  102.       goto ret;
  103.     }
  104.  
  105.   switch (cmd)
  106.     {
  107.     case TIOCGETA:
  108.       {
  109.         struct termios *t = (struct termios *)arg;
  110.         unsigned char *cp;
  111.         t->c_iflag = IGNBRK|IGNPAR|ICRNL|IXON;
  112.         t->c_oflag = (f->f_flags & FTTYRAW) ? 0 : OPOST|ONLCR;
  113.         t->c_cflag = CS8|CLOCAL;
  114.         t->c_ispeed=
  115.         t->c_ospeed= B38400;
  116.     /* Conman does ECHOCTL, Commo doesn't.. I use Conman:-)) */
  117.         t->c_lflag = ECHOCTL|((f->f_flags & FTTYRAW)?0:ICANON|ECHO);
  118.     /* t->c_line  = 0; */
  119.     cp = t->c_cc;
  120.     cp[VSTART] = 'q' & 31;
  121.     cp[VSTOP] = 's' & 31;
  122.     cp[VSUSP] = 0; /* sneef.. would that be nice... */
  123.     cp[VDSUSP] = 0;
  124.     cp[VREPRINT] = 0;
  125.     cp[VDISCARD] = 'x' & 31;
  126.     cp[VWERASE] = 0;
  127.     cp[VLNEXT] = 0;
  128.     cp[VSTATUS] = 0;
  129.     cp[VINTR] = 3;
  130.     cp[VQUIT] = 0;
  131.     cp[VERASE] = 8;
  132.     cp[VKILL] = 'x' & 31;
  133.     cp[VEOF] = '\\' & 31;
  134.     cp[VEOL] = 10;
  135.     cp[VEOL2] = 0;
  136.     result = 0;
  137.     goto ret;
  138.       }
  139.  
  140.     case TIOCSETA:
  141.     case TIOCSETAW:
  142.     case TIOCSETAF:
  143.       {
  144.         struct termios *t = (struct termios *)arg;
  145.         int makeraw;
  146.         
  147.         makeraw = (t->c_lflag & (ICANON | ECHO)) != (ICANON | ECHO);
  148.     /* the only thing that counts so far.. if ICANON is disabled,        
  149.      * we disable ECHO too, no matter what the user wanted, and 
  150.      * send a RAW-packet.. */
  151.     if (!makeraw && (f->f_flags & FTTYRAW))
  152.           {
  153.         f->f_flags &= ~FTTYRAW;
  154.         __wait_packet(&f->f_sp);
  155.         SendPacket1(f,__rwport,ACTION_SCREEN_MODE,0);
  156.         __wait_packet(&f->f_sp);
  157.       }
  158.     else if (makeraw && !(f->f_flags & FTTYRAW))
  159.       {
  160.         f->f_flags |= FTTYRAW;
  161.         __wait_packet(&f->f_sp);
  162.         SendPacket1(f,__rwport,ACTION_SCREEN_MODE,-1);
  163.         __wait_packet(&f->f_sp);
  164.       }
  165.     result = 0;
  166.     goto ret;
  167.       }
  168.  
  169.     case TIOCGETP:
  170.       {
  171.     struct sgttyb *s = (struct sgttyb *)arg;
  172.     s->sg_erase = 8;
  173.     s->sg_kill = 'x' & 31;
  174.     s->sg_flags = ODDP|EVENP|ANYP|
  175.               ((f->f_flags&FTTYRAW) ? (CBREAK|RAW) : (ECHO|CRMOD));
  176.     s->sg_ispeed =
  177.     s->sg_ospeed = OEXTB;
  178.     result = 0;
  179.     goto ret;
  180.       }
  181.  
  182.     case TIOCSETN:
  183.     case TIOCSETP:
  184.       {
  185.     struct sgttyb *s = (struct sgttyb *)arg;
  186.     if (!(s->sg_flags & (RAW|CBREAK)) /*&& (f->f_flags & FTTYRAW)*/)
  187.           {
  188.             f->f_flags &= ~FTTYRAW;
  189.         __wait_packet(&f->f_sp);
  190.         SendPacket1(f,__rwport,ACTION_SCREEN_MODE,0);
  191.         __wait_packet(&f->f_sp);
  192.       }
  193.         else if ((s->sg_flags & (RAW|CBREAK)) /*&& !(f->f_flags & FTTYRAW)*/)
  194.       {
  195.         f->f_flags |= FTTYRAW;
  196.         SendPacket1(f,__rwport,ACTION_SCREEN_MODE,-1);
  197.         __wait_packet(&f->f_sp);
  198.       }
  199.     result = 0;
  200.     goto ret;
  201.       }
  202.  
  203.     case TIOCGWINSZ:
  204.       {
  205.     struct winsize *ws = (struct winsize *) arg;
  206.     struct ConUnit *cu;
  207.     struct IOStdReq *ios;
  208.     struct InfoData *info;
  209.     struct Window *w;
  210.  
  211.     err = EINVAL;    /* default */
  212.     
  213.     info = alloca (sizeof (struct InfoData) + 2);
  214.     info = LONG_ALIGN (info);
  215.     bzero (info, sizeof (struct InfoData));
  216.     
  217.     /* VERY! strange.. CNC: won't act on the packet if it sent with the
  218.        async port as reply port! The error is OBJECT_IN_USE (202)... */
  219.  
  220.     __wait_packet (&f->f_sp);
  221.     LastResult (f) = 0; LastError (f) = 0;
  222.     SendPacket1 (f, u.u_sync_mp, ACTION_DISK_INFO, CTOBPTR (info));
  223.     __wait_sync_packet (&f->f_sp);
  224.     if (LastResult (f) != -1)
  225.       {
  226. /*        syscall (SYS_strncmp, "ACTION_DISK_INFO failed!", "", LastError(f));*/
  227.         goto ret;
  228.       }
  229.  
  230.     w = (struct Window *) info->id_VolumeNode;
  231.     if (! w) 
  232.       {
  233. /*        syscall (SYS_index, "No window in InfoData structure!", 0);*/
  234.         goto ret;
  235.       }
  236.     /* this information is from DevCon notes, not from the Bantam book */
  237.     ios = (struct IOStdReq *) info->id_InUse;
  238.     if (! ios || ((int)ios & 1)) 
  239.       {
  240. /*        syscall (SYS_index, "invalid ConUnit pointer in InfoData!", 0);*/
  241.         goto ret;
  242.       }
  243.     cu = (struct ConUnit *) ios->io_Unit;
  244.     if (!cu) 
  245.       {
  246. /*        syscall (SYS_index, "no ConUnit pointer in InfoData!", 0);*/
  247.         goto ret;
  248.       }
  249.  
  250.     /* paranoid check.. */
  251.     if (cu->cu_Window != w)
  252.       {
  253. /*        syscall (SYS_index, "incompatible ConUnit pointer in InfoData!", 0);*/
  254.         goto ret;
  255.       }
  256.  
  257.         ws->ws_xpixel = w->Width - w->BorderLeft - w->BorderRight;
  258.         ws->ws_ypixel = w->Height - w->BorderTop - w->BorderBottom;
  259.  
  260.     ws->ws_col = cu->cu_XMax + 1;    /* Thanks Rob! those values are off */
  261.     ws->ws_row = cu->cu_YMax + 1;    /* by one! */
  262.  
  263.     result = 0;
  264.     goto ret;
  265.       }
  266.  
  267.     case TIOCOUTQ:
  268.       {
  269.     int *count = (int *)arg;
  270.     *count = 0;
  271.     result = 0;
  272.     goto ret;
  273.       }
  274.  
  275.     case TIOCSWINSZ:
  276.       /* should I really try to resize the window ?? */
  277.  
  278.     default:
  279.       /* this is no error, but nevertheless we don't take any actions.. */      
  280.       result = 0;
  281.       goto ret;
  282.     }
  283.  
  284. ret:
  285.     LastResult(f) = 0;
  286.     __release_file (f);
  287.     syscall (SYS_sigsetmask, omask);
  288.     errno = err;
  289.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  290.     return result;
  291. }
  292.